home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DKBSRC.ARJ / XWIN.C < prev   
C/C++ Source or Header  |  1991-05-04  |  9KB  |  330 lines

  1. /*
  2.     Here are some routines I wrote which implement +d option on
  3.     unix computers running X-windows. For now, only black
  4.     and white output is supported. If I get access to a computer
  5.     with a color monitor, I'll probably add support for colors to
  6.     my routines. 
  7.  
  8.     In future I'll probably add some more dithering methods.
  9.     I have tested these routines on SUN 3 and SUN 4. I'm using
  10.     the tvtwm window manager. 
  11.  
  12.     If you have some suggestions to my source code or if you change
  13.     anything, please let me know. I can be reached at the following
  14.     address: Marek Rzewuski, Avstikkeren 11, 1156 Oslo 11, Norway or
  15.     marekr@ifi.uio.no on Internet.
  16. */
  17.     
  18. #include <stdio.h>
  19. #include <X11/Xlib.h>        /* some Xlib stuff */
  20. #include <X11/Xutil.h>
  21. #include "theIcon"        
  22.  
  23. #include "frame.h"
  24. #include "dkbproto.h"
  25.  
  26. #define     BORDER_WIDTH    2
  27. #define    EV_MASK    (ButtonPressMask | \
  28.          KeyPressMask     | \
  29.          ExposureMask    | \
  30.          StructureNotifyMask)
  31.  
  32. Display        *theDisplay;
  33. int        theScreen;
  34. int        theDepth;
  35. unsigned long    theBlackPixel;
  36. unsigned long    theWhitePixel;
  37. XEvent        theEvent;    
  38. Window      theWindow, openWindow();
  39. GC        theGC;
  40. unsigned char    *bitmap;     /* pointer to our picture bitmap */
  41. unsigned char    *bitmapPos;     /* position to the last drawn pixel in our bitmap */
  42.  
  43.  
  44. /* global DKBTrace variables */
  45.  
  46. extern FRAME Frame;
  47. extern unsigned int Options;
  48. extern char DisplayFormat;
  49. extern int First_Line;
  50.  
  51. enum pixval { BLACK, WHITE };
  52.  
  53. /* an dither matrix used to produce some dithering when using black/white screen */
  54. int dither_matrix[8][8] = {
  55.     {  2, 60, 16, 56,  3, 57, 13, 53 },
  56.     { 34, 18, 48, 32, 35, 19, 45, 29 },
  57.     { 10, 50,  6, 64, 11, 51,  7, 61 },
  58.     { 42, 26, 38, 22, 43, 27, 39, 23 },
  59.     {  4, 58, 14, 54,  1, 59, 15, 55 },
  60.     { 36, 20, 46, 30, 33, 17, 47, 31 },
  61.     { 44, 28, 40, 24, 41, 25, 37, 21 },
  62.     {  2, 60, 16, 56,  3, 57, 13, 53 }};
  63.  
  64. void unix_init_dkb_trace PARAMS ((void))
  65.    {
  66.    }
  67.  
  68. enum pixval
  69. dither(r, g, b, x, y)
  70.     int r, g, b, x, y;
  71. {
  72.     int greyval;
  73.  
  74.     /* They say those numbers are the best, don't ask me why... */
  75.     greyval = (0.299*r + 0.587*g  + 0.114*b) * 64. / 255.;
  76.     return (greyval < dither_matrix[x%8][y%8]) ? BLACK : WHITE;
  77. }
  78.  
  79.  
  80.  
  81.  
  82. /* Sets up a connection to the X server and stores informations about the enviroment */
  83.  
  84. initX()
  85. {
  86.   theDisplay = XOpenDisplay(NULL);
  87.   if (theDisplay == NULL) {
  88.     fprintf(stderr,"ERROR: Cannot establish a connection to the X server %s\n",
  89.         XDisplayName(NULL));
  90.     exit(1);
  91.   }
  92.   theScreen = DefaultScreen(theDisplay);
  93.   theDepth  = DefaultDepth(theDisplay, theScreen);
  94.   theWhitePixel = WhitePixel(theDisplay, theScreen);
  95.   theBlackPixel = BlackPixel(theDisplay, theScreen);
  96. }
  97.  
  98. /* This procedure will do the following things:
  99.    1)     Set up attributes desired for the window
  100.    2)    Set up an icon to our window.
  101.    3)     Send hints to the window manager.
  102.    4)     Open a window on the display
  103.    5)    Tell the X to place the window on the screen
  104.    6)    Flush out all the queued up X requests to the X server */
  105.  
  106. Window openWindow(x,y,width,height,flag,theNewGC)
  107. int    x,y;
  108. int    width,height;
  109. int    flag;
  110. GC    *theNewGC;
  111. {
  112.   XSetWindowAttributes    theWindowAttributes;
  113.   XSizeHints        theSizeHints;
  114.   unsigned    long    theWindowMask;
  115.   Window        theNewWindow;
  116.   Pixmap         theIconPixmap;
  117.   XWMHints        theWMHints;
  118.  
  119.  
  120.   /* Set up some attributes for the window. Override_redirect tells
  121.      the window manager to deal width the window or leave it alone */
  122.  
  123.   theWindowAttributes.border_pixel     = theBlackPixel;
  124.   theWindowAttributes.background_pixel     = theWhitePixel;
  125.   theWindowAttributes.override_redirect = False;
  126.   theWindowMask = CWBackPixel | CWBorderPixel | CWOverrideRedirect;
  127.  
  128.   /* Now, open out window */
  129.   
  130.   theNewWindow = XCreateWindow(theDisplay,
  131.                    RootWindow(theDisplay,theScreen),
  132.                    x,y,
  133.                    width, height,
  134.                    BORDER_WIDTH,
  135.                    theDepth,
  136.                    InputOutput,
  137.                    CopyFromParent,
  138.                    theWindowMask,
  139.                    &theWindowAttributes);
  140.  
  141.   /* Create one iconbitmap */
  142.  
  143.   theIconPixmap = XCreateBitmapFromData(theDisplay,
  144.                     theNewWindow,
  145.                     theIcon_bits,
  146.                     theIcon_width,
  147.                     theIcon_height);
  148.  
  149.   /* Now tell the window manager where on screen we should place our 
  150.      window. */
  151.  
  152.   theWMHints.icon_pixmap    = theIconPixmap;
  153.   theWMHints.initial_state     = NormalState;         /* we don't want an iconized window when it's created */
  154.   theWMHints.flags        = IconPixmapHint | StateHint;
  155.  
  156.   XSetWMHints(theDisplay,theNewWindow,&theWMHints);
  157.  
  158.   theSizeHints.flags        = PPosition | PSize;
  159.   theSizeHints.x        = x;
  160.   theSizeHints.y        = y;
  161.   theSizeHints.width        = width;
  162.   theSizeHints.height        = height;
  163.  /* theSizeHints.min_width    = width;
  164.   theSizeHints.min_height    = height;
  165.   theSizeHints.max_width    = width;
  166.   theSizeHints.max_height    = height; */
  167.  
  168.   XSetNormalHints(theDisplay,theNewWindow,&theSizeHints);
  169.  
  170.  
  171.   if (createGC(theNewWindow, theNewGC) == 0) {
  172.     XDestroyWindow(theDisplay, theNewWindow);
  173.     return((Window) 0);
  174.   } 
  175.  
  176.   /* make a name for our window */
  177.   
  178.   XStoreName(theDisplay, theNewWindow, "DKBTrace v2.10\0");
  179.  
  180.   /* Now, could we please see the window on the screen?
  181.      Until now, we have dealed with a window which has been created
  182.      but noe appeared on the screen. Maping the window places it visibly    
  183.      on the screen */
  184.  
  185.   XMapWindow(theDisplay,theNewWindow);
  186.   XFlush(theDisplay);
  187.   return(theNewWindow);
  188. }
  189.  
  190. refreshWindow(theExposedWindow)
  191. Window     theExposedWindow;
  192. {
  193.   int    i, x, y;    
  194.   unsigned char    *dummy;
  195.   dummy = bitmap;
  196.   i = 0; x= 0; y = First_Line;
  197.   do {
  198.     if (*dummy) 
  199.       XDrawPoint(theDisplay, theWindow, theGC,x,y);
  200.     if (x == Frame.Screen_Width) {
  201.       x = 0;
  202.       y++;
  203.     } else {
  204.       dummy++;
  205.       x++;
  206.       i++;
  207.     }
  208.   } while(dummy != bitmapPos);        /* until dummy = the last drawn pixel in our window */
  209.   XFlush(theDisplay);
  210. }
  211.  
  212. /* Creates a new graphics context */
  213.  
  214. createGC(theNewWindow, theNewGC)
  215. Window     theNewWindow;
  216. GC    *theNewGC;
  217. {
  218.   XGCValues theGCValues;
  219.   *theNewGC = XCreateGC(theDisplay,
  220.             theNewWindow, 
  221.             (unsigned long) 0,
  222.             &theGCValues);
  223.  
  224.   if (*theNewGC == 0) {
  225.     return(0); /*error*/
  226.   } else { /* set foreground and background defaults for the new GC */
  227.     XSetForeground(theDisplay,
  228.            *theNewGC,
  229.            theBlackPixel);
  230.     
  231.     XSetBackground(theDisplay,
  232.           *theNewGC,
  233.           theWhitePixel);
  234.  
  235.     return(1); /* OK */
  236.   }
  237. }
  238.     
  239. initEvents(theWindow)
  240. Window theWindow;
  241. {
  242.   XSelectInput(theDisplay,
  243.            theWindow,
  244.            EV_MASK);
  245. }
  246.  
  247. void display_finished ()
  248. {
  249.   
  250. }
  251.  
  252.  
  253. void display_init ()
  254. {
  255.   int    i;
  256.  
  257.   /* set some room for a bitmap for our picture. I've got to "remember" the whole
  258.      picture bacuse of resising of the window, overlaping etc. Then I've got to
  259.      refresh the picture. This should be easy to convert to an "color version" in
  260.      future */
  261.    
  262.   bitmap = (unsigned char *) malloc(sizeof(unsigned char) * (Frame.Screen_Width * Frame.Screen_Height));
  263.   bitmapPos = bitmap;
  264.   if (bitmap == NULL) 
  265.     printf("ERROR: Can not allocate the buffer..\n");
  266.   
  267.   for (i = 0; i < (Frame.Screen_Width*Frame.Screen_Height); i++) {   
  268.     *bitmapPos++ = 0;  
  269.   }
  270.   bitmapPos = bitmap;
  271.   initX();
  272.   theWindow = openWindow(0,0,Frame.Screen_Width,Frame.Screen_Height,0,&theGC);
  273.   initEvents(theWindow);
  274.   XFlush(theDisplay); 
  275.   XNextEvent(theDisplay,&theEvent);
  276.   XFlush(theDisplay); 
  277. } /* end of display initilazation */
  278.  
  279. void display_close ()
  280. {
  281.   sleep(10);                /* an simple delay. 10 seconds. */
  282.   XDestroyWindow(theDisplay,theWindow);
  283.   XFlush(theDisplay);
  284.   XCloseDisplay(theDisplay);
  285.   free(bitmap);
  286. }
  287.  
  288. void display_plot (x, y, Red, Green, Blue)
  289. int x, y;
  290. unsigned char Red, Green, Blue;
  291. {
  292.   unsigned char     color;
  293.   int            numEvents;
  294.   /* lets find if there are some events waiting for us */
  295.  
  296.   numEvents = XPending(theDisplay);
  297.   if (numEvents > 0) {             /* now deal with the events.. */  
  298.     XNextEvent(theDisplay,&theEvent);
  299.     
  300.     switch (theEvent.type) {
  301.     case Expose:
  302.       /*printf("Window is exposed.\n");*/
  303.       refreshWindow(theEvent.xany.window);
  304.       break;
  305.   
  306.     case MapNotify:
  307.       /*printf("The window is mapped.\n");*/
  308.       refreshWindow(theEvent.xany.window);
  309.       break;
  310.  
  311.     case ButtonPress:
  312.       /*printf("A mouse button was pressed.\n");*/
  313.       break;
  314.  
  315.     case ConfigureNotify:
  316.       /*printf("The window configuration has been changed\n");*/
  317.       refreshWindow(theEvent.xany.window);
  318.       break;
  319.     }
  320.   }
  321.   color = (!dither(Red, Green, Blue, x, y));
  322.   
  323.   *bitmapPos = color;
  324.   if (color) 
  325.     XDrawPoint(theDisplay, theWindow, theGC,x,y); 
  326.   bitmapPos++;
  327.   /*XFlush(theDisplay); Let's be nice to the network, OK? */
  328. }
  329.  
  330.